#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#include "common.h"

unsigned int sum; // Global variable definition

void * runner(void * param)
{
    int upper = atoi(param) * 4;

    sum = 0;

    for (unsigned int i = 1; i <= upper; i++)
    {
        sum++;
    }

    sleep(10);

    pthread_exit(0); // Child thread exits
}

void thread_new(int param, char * argv[])
{
    pthread_t
    t1id,
    t2id;
    pthread_attr_t
    t1attr,
    t2attr;

    // Thread creation
    pthread_attr_init(&t1attr);
    pthread_create(&t1id, &t1attr, runner, argv[1]);

    pthread_attr_init(&t2attr);
    pthread_create(&t2id, &t2attr, runner, argv[1]);

    // Main (parent) thread waiting for exit of child thread
    pthread_join(t1id, NULL);
    pthread_join(t2id, NULL);
}

int main(int argc, char * argv[])
{
    int p1, p2, pr;
    p1 = p2 = pr = 0;

    p1 = fork();
    p2 = fork();

    if (p1 < 0 || p2 < 0)
    {
        printf("Error occurred");
        br(1);
    } else if (p1 == 0 || p2 == 0) // Child process
    {
        if (argc != 2) // Notice that count included the executable file name.
        {
            fprintf(stderr, "Usage: *executable file name* <integer value>");
            stderr_br(1);

            return -1;
        }

        int param = atoi(argv[1]);
        if (param < 0)
        {
            fprintf(stderr, "%d must be >= 0", param);
            stderr_br(1);

            return -1;
        }

        thread_new(param, argv);
        sleep(5);
    } else {
        pr = wait(NULL);
        if (pr)
        {
            printf("Child process with PID %d", pr);
            br(1);
        }

        pr = wait(NULL);
        if (pr)
        {
            printf("Child process with PID %d", pr);
            br(1);
        }

        printf("Sum = %d", sum);
        br(1);
    }

    return 0;
}
